﻿using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using BattleMaster_IRCbot.UserCommands;

namespace BattleMaster_IRCbot
{
    class Stats
    {
        public int HitPoints,
            maxHitPoints,
            MagicPoints,
            maxMagicPoints,
            Strength,
            Dexterity,
            Agility,
            Defence;

        public Stats()
        {
            this.HitPoints = 0;
            this.maxHitPoints = 0;
            this.MagicPoints = 0;
            this.maxMagicPoints = 0;
            this.Strength = 0;
            this.Dexterity = 0;
            this.Agility = 0;
            this.Defence = 0;
        }
    }

    class Equipment
    {
        public WornItem Head,
            Neck,
            Torso,
            Shoulders,
            LeftArm,
            RightArm,
            LeftHand,
            RightHand,
            Waist,
            Legs,
            Feet;

        public Equipment()
        {
            Neck = null;
            Torso = null;
            Shoulders = null;
            LeftArm = null;
            RightArm = null;
            LeftHand = null;
            RightHand = null;
            Waist = null;
            Legs = null;
            Feet = null;
        }
    }

    class Character
    {
        private string _Name;
        private Stats CharacterStats;
        private List<Command> _commands;
        private Equipment _equipment;
        private List<Item> _inventory;

        public string Name
        {
            get { return this._Name;}
            set { this._Name = value; }
        }
        public List<Command> Commands
        {
            get { return this._commands; }
        }
        public int HitPoints
        {
            get { return this.CharacterStats.HitPoints; }
            set { this.CharacterStats.HitPoints = value; }
        }
        public int MaigicPoints
        {
            get { return this.CharacterStats.MagicPoints; }
            set { this.CharacterStats.MagicPoints = value; }
        }
        public int maxHitPoints
        {
            get { return this.CharacterStats.maxHitPoints; }
            set { this.CharacterStats.maxHitPoints = value; }
        }
        public int maxMagicPoints
        {
            get { return this.CharacterStats.maxMagicPoints; }
            set { this.CharacterStats.maxMagicPoints = value; }
        }
        public int Strength
        {
            get { return this.CharacterStats.Strength; }
            set { this.CharacterStats.Strength = value; }
        }
        public int Dexterity
        {
            get { return this.CharacterStats.Dexterity; }
            set { this.CharacterStats.Dexterity = value; }
        }
        public int Agility
        {
            get { return this.CharacterStats.Agility; }
            set { this.CharacterStats.Agility = value; }
        }
        public int Defence
        {
            get { return this.CharacterStats.Defence; }
            set { this.CharacterStats.Defence = value; }
        }

        public Character(string playerNick)
        {
            _Name = playerNick;
            CharacterStats = new Stats();
            _commands = new List<Command>();
            _inventory = new List<Item>();
            try { LoadCharacter(playerNick); }
            catch (DirectoryNotFoundException ex) { throw ex; }
            catch (FileNotFoundException ex) { throw ex; }

            _commands.Add(new Attack());
        }

        public List<Item> getInventory()
        {
            return _inventory;
        }

        private void LoadCharacter(string playerNick)
        {
            string activeDirectory = Directory.GetCurrentDirectory();

            //Find number of lines in character file.
            string filePath = activeDirectory + @"\Players\" + playerNick + ".txt";
            int numLines;
            try { numLines = File.ReadLines(filePath).Count(); }
            catch (DirectoryNotFoundException ex) { throw new DirectoryNotFoundException("Players directory not found. Did the program initialize properly?", ex); }
            catch (FileNotFoundException ex) { throw new FileNotFoundException("Player file not found.", ex); }
            //Read character fileinto memory
            string[] characterBuffer = File.ReadAllLines(filePath);

            //Analyse character file
            for (int i = 0; i < numLines; i++)
            {
                //Switch logic based on what section of the character data the program is reading though.
                switch (characterBuffer[i])
                {
                    case "--Character":
                        //Itterate through the character section
                        for (int b = 1; b < numLines - i; i++)
                        {
                            int currentIndex = i + b;
                            //Continue to the end of the section, terminated by "--" (The beginnig of a new section)
                            if (!characterBuffer[currentIndex].StartsWith("--"))
                            {
                                //Split the string where ':' appears
                                string[] statBuffer = characterBuffer[currentIndex].Split(':');
                                string[] statSplit;

                                //Switch based on what stat is on the current line
                                switch (statBuffer[0])
                                {
                                    case "HP":
                                        statSplit = statBuffer[1].Split('/');
                                        try
                                        {
                                            this.HitPoints = Convert.ToInt32(statSplit[0]);
                                            this.maxHitPoints = Convert.ToInt32(statSplit[1]);
                                        }
                                        catch (FormatException e) { Console.WriteLine("Input string is not a sequence of digits."); }
                                        catch (OverflowException e) { Console.WriteLine("The number cannot fit in an Int32."); }
                                        break;
                                    case "MP":
                                        statSplit = statBuffer[1].Split('/');
                                        try
                                        {
                                            this.MaigicPoints = Convert.ToInt32(statSplit[0]);
                                            this.maxMagicPoints = Convert.ToInt32(statSplit[1]);
                                        }
                                        catch (FormatException e) { Console.WriteLine("Input string is not a sequence of digits."); }
                                        catch (OverflowException e) { Console.WriteLine("The number cannot fit in an Int32."); }
                                        break;
                                    case "Strength":
                                        try { this.Strength = Convert.ToInt32(statBuffer[1]); }
                                        catch (FormatException e) { Console.WriteLine("Input string is not a sequence of digits."); }
                                        catch (OverflowException e) { Console.WriteLine("The number cannot fit in an Int32."); }
                                        break;
                                    case "Dexterity":
                                        try { this.Dexterity = Convert.ToInt32(statBuffer[1]); }
                                        catch (FormatException e) { Console.WriteLine("Input string is not a sequence of digits."); }
                                        catch (OverflowException e) { Console.WriteLine("The number cannot fit in an Int32."); }
                                        break;
                                    case "Agility":
                                        try { this.Agility = Convert.ToInt32(statBuffer[1]); }
                                        catch (FormatException e) { Console.WriteLine("Input string is not a sequence of digits."); }
                                        catch (OverflowException e) { Console.WriteLine("The number cannot fit in an Int32."); }
                                        break;
                                    case "Defence":
                                        try { this.Defence = Convert.ToInt32(statBuffer[1]); }
                                        catch (FormatException e) { Console.WriteLine("Input string is not a sequence of digits."); }
                                        catch (OverflowException e) { Console.WriteLine("The number cannot fit in an Int32."); }
                                        break;
                                }
                            }
                            else break; //This is the termination of the Character section analysis.
                        }
                        break;
                    case "--Inventory":
                        //Nothing being done with inventory yet.
                        break;
                }
            }
        }

        public string statString()
        {
            string output = String.Format("HP: {0}/{1} | MP: {2}/{3}", HitPoints, maxHitPoints, MaigicPoints, maxMagicPoints);
            return output;
        }
    }
}
